001 /* 002 * Copyright 2005 Stephen J. McConnell 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 013 * implied. 014 * 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018 019 package net.dpml.library.info; 020 021 import java.io.OutputStream; 022 import java.io.IOException; 023 import java.io.Writer; 024 import java.io.OutputStreamWriter; 025 import java.util.Properties; 026 027 import net.dpml.lang.Category; 028 import net.dpml.lang.Version; 029 030 import net.dpml.library.info.IncludeDirective.Mode; 031 032 033 /** 034 * Utility class used for construction of a module model from an XML source. 035 * 036 * @author <a href="http://www.dpml.net">Digital Product Meta Library</a> 037 * @version 1.1.0 038 */ 039 public final class LibraryEncoder extends LibraryConstants 040 { 041 /** 042 * Write a module directive to an output stream as a portable XML definition. 043 * During export dependencies are limited to runtime concerns (eliminating 044 * build and test scoped dependencies). Artifact production is strippped down 045 * to a generic type declaration. The resulting XML file is suitable for 046 * publication and usage by external projects. 047 * 048 * @param module the module directive to externalize 049 * @param output the output stream 050 * @exception IOException if an error occurs during module externalization 051 */ 052 public void export( final ModuleDirective module, final OutputStream output ) throws IOException 053 { 054 final Writer writer = new OutputStreamWriter( output ); 055 try 056 { 057 writer.write( XML_HEADER ); 058 writer.write( "\n" ); 059 060 String name = module.getName(); 061 String version = module.getVersion(); 062 063 if( null != name ) 064 { 065 writer.write( "<module name=\"" + name + "\"" ); 066 } 067 if( null != version ) 068 { 069 writer.write( " version=\"" + version + "\"" ); 070 } 071 072 writer.write( 073 "\n xmlns=\"" 074 + MODULE_XSD_URI 075 + "\">" ); 076 077 String basedir = module.getBasedir(); 078 InfoDirective info = module.getInfoDirective(); 079 Properties properties = module.getProperties(); 080 TypeDirective[] types = module.getTypeDirectives(); 081 DependencyDirective[] dependencies = module.getDependencyDirectives(); 082 ResourceDirective[] resources = module.getResourceDirectives(); 083 084 if( !info.isNull() ) 085 { 086 writer.write( "\n" ); 087 writeInfo( writer, info, " " ); 088 } 089 if( properties.size() > 0 ) 090 { 091 writer.write( "\n" ); 092 writeProperties( writer, properties, " ", true ); 093 } 094 if( types.length > 0 ) 095 { 096 writer.write( "\n" ); 097 writeTypes( writer, types, " " ); 098 } 099 if( dependencies.length > 0 ) 100 { 101 writer.write( "\n" ); 102 writeDependencies( writer, dependencies, " " ); 103 } 104 if( resources.length > 0 ) 105 { 106 writeResources( writer, resources, " " ); 107 } 108 writer.write( "\n\n</module>" ); 109 writer.write( "\n" ); 110 } 111 finally 112 { 113 writer.flush(); 114 writer.close(); 115 } 116 } 117 118 private void writeModule( Writer writer, ModuleDirective module, String lead ) throws IOException 119 { 120 String name = module.getName(); 121 String version = module.getVersion(); 122 123 InfoDirective info = module.getInfoDirective(); 124 Properties properties = module.getProperties(); 125 String basedir = module.getBasedir(); 126 TypeDirective[] types = module.getTypeDirectives(); 127 DependencyDirective[] dependencies = module.getDependencyDirectives(); 128 ResourceDirective[] resources = module.getResourceDirectives(); 129 130 writer.write( "\n" + lead + "<module" ); 131 if( null != name ) 132 { 133 writer.write( " name=\"" + name + "\"" ); 134 } 135 if( null != version ) 136 { 137 writer.write( " version=\"" + version + "\"" ); 138 } 139 writer.write( ">" ); 140 141 if( !info.isNull() ) 142 { 143 writer.write( "\n" ); 144 writeInfo( writer, info, lead + " " ); 145 } 146 if( properties.size() > 0 ) 147 { 148 writer.write( "\n" ); 149 writeProperties( writer, properties, lead + " ", true ); 150 } 151 152 if( types.length > 0 ) 153 { 154 writer.write( "\n" ); 155 writeTypes( writer, types, lead + " " ); 156 } 157 158 if( dependencies.length > 0 ) 159 { 160 writer.write( "\n" ); 161 writeDependencies( writer, dependencies, lead + " " ); 162 } 163 164 if( resources.length > 0 ) 165 { 166 writeResources( writer, resources, lead + " " ); 167 } 168 writer.write( "\n\n" + lead + "</module>" ); 169 } 170 171 private void writeResource( Writer writer, ResourceDirective resource, String lead ) throws IOException 172 { 173 String name = resource.getName(); 174 String version = resource.getVersion(); 175 176 InfoDirective info = resource.getInfoDirective(); 177 Properties properties = resource.getProperties(); 178 String basedir = resource.getBasedir(); 179 TypeDirective[] types = resource.getTypeDirectives(); 180 DependencyDirective[] dependencies = resource.getDependencyDirectives(); 181 182 writer.write( "\n" + lead + "<resource" ); 183 if( null != name ) 184 { 185 writer.write( " name=\"" + name + "\"" ); 186 } 187 if( null != version ) 188 { 189 writer.write( " version=\"" + version + "\"" ); 190 } 191 writer.write( ">" ); 192 193 if( !info.isNull() ) 194 { 195 writer.write( "\n" ); 196 writeInfo( writer, info, lead + " " ); 197 } 198 if( properties.size() > 0 ) 199 { 200 writeProperties( writer, properties, lead + " ", true ); 201 } 202 if( types.length > 0 ) 203 { 204 writeTypes( writer, types, lead + " " ); 205 } 206 if( dependencies.length > 0 ) 207 { 208 writeDependencies( writer, dependencies, lead + " " ); 209 } 210 writer.write( "\n" + lead + "</resource>" ); 211 } 212 213 private void writeInfo( 214 Writer writer, InfoDirective info, String lead ) throws IOException 215 { 216 writer.write( lead + "<info" ); 217 if( null != info.getTitle() ) 218 { 219 writer.write( " title=\"" + info.getTitle() + "\"" ); 220 } 221 String description = info.getDescription(); 222 if( null != description ) 223 { 224 writer.write( ">" ); 225 writer.write( "\n" + lead + " <description>" ); 226 writer.write( "\n" + lead + " " + description ); 227 writer.write( "\n" + lead + " </description>" ); 228 writer.write( "\n" + lead + "</info>" ); 229 } 230 else 231 { 232 writer.write( "/>" ); 233 } 234 } 235 236 private void writeProperties( 237 Writer writer, Properties properties, String lead, boolean flag ) throws IOException 238 { 239 if( properties.size() > 0 ) 240 { 241 if( flag ) 242 { 243 writer.write( "\n" + lead + "<properties>" ); 244 } 245 String[] names = (String[]) properties.keySet().toArray( new String[0] ); 246 for( int i=0; i<names.length; i++ ) 247 { 248 String name = names[i]; 249 String value = properties.getProperty( name ); 250 writer.write( "\n" + lead ); 251 if( flag ) 252 { 253 writer.write( " " ); 254 } 255 writer.write( "<property name=\"" + name + "\" value=\"" + value + "\"/>" ); 256 } 257 if( flag ) 258 { 259 writer.write( "\n" + lead + "</properties>" ); 260 } 261 } 262 } 263 264 private void writeTypes( Writer writer, TypeDirective[] types, String lead ) throws IOException 265 { 266 if( types.length > 0 ) 267 { 268 writer.write( "\n" + lead + "<types>" ); 269 for( int i=0; i<types.length; i++ ) 270 { 271 TypeDirective type = types[i]; 272 writeType( writer, type, lead + " " ); 273 } 274 writer.write( "\n" + lead + "</types>" ); 275 } 276 } 277 278 private void writeType( Writer writer, TypeDirective type, String lead ) throws IOException 279 { 280 String id = type.getID(); 281 writer.write( "\n" + lead + "<type id=\"" + id + "\"" ); 282 Version version = type.getVersion(); 283 if( null != version ) 284 { 285 if( Version.NULL_VERSION.equals( version ) ) 286 { 287 writer.write( " alias=\"true\"" ); 288 } 289 else 290 { 291 writer.write( " version=\"" + version.getMajor() + "." + version.getMinor() + "\"" ); 292 } 293 } 294 writer.write( "/>" ); 295 } 296 297 private void writeDependencies( 298 Writer writer, DependencyDirective[] dependencies, String lead ) throws IOException 299 { 300 if( dependencies.length > 0 ) 301 { 302 writer.write( "\n" + lead + "<dependencies>" ); 303 304 for( int i=0; i<dependencies.length; i++ ) 305 { 306 DependencyDirective dependency = dependencies[i]; 307 IncludeDirective[] includes = dependency.getIncludeDirectives(); 308 if( includes.length > 0 ) 309 { 310 Scope scope = dependency.getScope(); 311 String label = scope.toString().toLowerCase(); 312 writer.write( "\n" + lead + " <" + label + ">" ); 313 for( int j=0; j<includes.length; j++ ) 314 { 315 IncludeDirective include = includes[j]; 316 Mode mode = include.getMode(); 317 String value = include.getValue(); 318 writer.write( "\n" + lead + " <include" ); 319 if( Mode.KEY.equals( mode ) ) 320 { 321 writer.write( " key=\"" + value + "\"" ); 322 } 323 else if( Mode.REF.equals( mode ) ) 324 { 325 writer.write( " ref=\"" + value + "\"" ); 326 } 327 else if( Mode.URI.equals( mode ) ) 328 { 329 writer.write( " uri=\"" + value + "\"" ); 330 } 331 332 if( Scope.RUNTIME.equals( scope ) ) 333 { 334 Category category = include.getCategory(); 335 if( !Category.PRIVATE.equals( category ) ) 336 { 337 String name = category.getName().toLowerCase(); 338 writer.write( " tag=\"" + name + "\"" ); 339 } 340 } 341 342 Properties props = include.getProperties(); 343 if( props.size() > 0 ) 344 { 345 writer.write( ">" ); 346 writeProperties( writer, props, lead + " ", false ); 347 writer.write( "\n" + lead + " </include>" ); 348 } 349 else 350 { 351 writer.write( "/>" ); 352 } 353 } 354 writer.write( "\n" + lead + " </" + label + ">" ); 355 } 356 } 357 writer.write( "\n" + lead + "</dependencies>" ); 358 } 359 } 360 361 private void writeResources( Writer writer, ResourceDirective[] resources, String lead ) throws IOException 362 { 363 for( int i=0; i<resources.length; i++ ) 364 { 365 ResourceDirective resource = resources[i]; 366 if( resource instanceof ModuleDirective ) 367 { 368 writer.write( "\n" ); 369 ModuleDirective module = (ModuleDirective) resource; 370 writeModule( writer, module, lead ); 371 } 372 else 373 { 374 writer.write( "\n" ); 375 writeResource( writer, resource, lead ); 376 } 377 } 378 } 379 }